package com.ldgame.entities;

import org.lwjgl.util.vector.Vector2f;
import org.newdawn.slick.Color;

import com.ldgame.game.Victory;
import com.ldgame.gfx.gfxelements.Sprite;
import com.ldgame.utils.Timer;

public class Entity {
	protected Vector2f position = new Vector2f(0.0f, 0.0f);
	protected float theta = 0.0f;
	protected float radius = 4.0f;
	protected float speed = 40.0f;
	protected Team team;
	protected Sprite sprite = new Sprite(position,
									     32.0f,
									     32.0f,
									     new Vector2f(0.0f, 64.0f),
									     new Vector2f(8.0f, 8.0f),
									     new Color(1.0f, 0.0f, 0.0f, 1.0f),
									     4,
									     0.125f);
	
	protected float timer = 0.0f;
	private float deathTimer = 0.0f;
	
	protected boolean enabled = true;
	protected boolean moving = false;
	protected boolean selected = false;
	
	public Entity(Team team) {
		this.team = team;
		
		sprite.setColor(new Color(1.0f, 1.0f, 1.0f, 1.0f));
		sprite.setTexCoord(new Vector2f(0.0f, (team == Team.TINY_HUMAN) ? 96.0f : 128.0f));
		sprite.setWidth(2.0f * radius);
		sprite.setHeight(2.0f * radius);
		sprite.setCamPosition(position);
	}
	
	public Vector2f getPosition() {
		return position;
	}
	
	public void setPosition(Vector2f position) {
		this.position = position;
		sprite.setPosition(position);
	}
	
	public float getTheta() {
		return theta;
	}

	public void setTheta(float theta) {
		this.theta = theta;
	}

	public float getRadius() {
		return radius;
	}

	public void setRadius(float radius) {
		this.radius = radius;
		sprite.setWidth(2.0f * radius);
		sprite.setHeight(2.0f * radius);
	}

	public float getSpeed() {
		return speed;
	}

	public void setSpeed(float speed) {
		this.speed = speed;
	}

	public float getTimer() {
		return timer;
	}

	public void setTimer(float timer) {
		this.timer = timer;
	}

	public Team getTeam() {
		return team;
	}

	public void setTeam(Team team) {
		this.team = team;
	}

	public boolean isMoving() {
		return moving;
	}

	public void setMoving(boolean moving) {
		this.moving = moving;
	}

	public boolean isEnabled() {
		return enabled;
	}

	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}

	public boolean isSelected() {
		return selected;
	}

	public void setSelected(boolean selected) {
		this.selected = selected;
	}

	public float getDeathTimer() {
		return deathTimer;
	}

	public void setDeathTimer(float deathTimer) {
		this.deathTimer = deathTimer;
	}

	public Sprite getSprite() {
		return sprite;
	}

	public void setSprite(Sprite sprite) {
		this.sprite = sprite;
	}

	private void move(float dirX, float dirY) {
		position.x += dirX;
		position.y += dirY;
	}
	
	public void sync(City [] cities) {
		sprite.sync(Timer.getLoopTime());
		timer += Timer.getLoopTime();
		
		if (isMoving()) {
			move((float)Math.cos(theta) * Timer.getLoopTime() * speed, (float)Math.sin(theta) * Timer.getLoopTime() * speed);
			if (position.x > 3250.0f) {
				position.x -= 6500.0f;
			} else if (position.x < -3250.0f) {
					   position.x += 6500.0f;
			}
			
			if (position.y > 3250.0f) {
				position.y -= 6500.0f;
			} else if (position.y < -3250.0f) {
					   position.y += 6500.0f;
			}
		}
		if (!(this instanceof Bullet)) {
			sprite.setSpriteState((int)((theta + 0.125f * (float)Math.PI) / (0.5f * (float)Math.PI) % 4));
		}
		
		if (!isEnabled()) {
			int kills = (team == Team.TINY_HUMAN) ? Victory.humansKilled : Victory.aliensKilled;
			if (deathTimer > 10.0f + ((float)kills / ((team == Team.TINY_HUMAN) ? 1200.0f : 1800.0f)) * 60.0f) {
				deathTimer = 0.0f;
				spawn(cities);
			}
			deathTimer += Timer.getLoopTime();
		}
	}
	
	public void spawn(City [] cities) {
		for (City city : cities) {
			if (city.getTeam() == getTeam() && !city.isContested()) {
				setEnabled(true);
				setPosition(new Vector2f(city.getBuildings()[(int)(Math.random() * city.getBuildings().length)].getPosition().x,
										 city.getBuildings()[(int)(Math.random() * city.getBuildings().length)].getPosition().y + 64.0f));
			}
		}
	}
	
	public void handleCollisions(Entity entity) {
		if (this != entity && 
			enabled && entity.isEnabled() &&
			Vector2f.sub(entity.getPosition(), getPosition(), null).length() < entity.getRadius() + getRadius()) {
			double theta = Math.atan2(entity.getPosition().y - getPosition().y, entity.getPosition().x - getPosition().x);
			float speed = entity.getSpeed();
			
			entity.setSpeed(getSpeed());
			entity.move((float)Math.cos(theta), (float)Math.sin(theta));
			entity.setSpeed(speed);
		}
	}
	
	public void render() {
		sprite.render();
	}
}
